package com.hup.minicontroller.server.androidService;

import android.app.Notification;
import android.app.Notification.Builder;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import com.hup.minicontroller.common.framework.MainThreadHandler;
import com.hup.minicontroller.server.ServerApplication;
import com.hup.minicontroller.server.mvp.IScreenImageService;
import com.hup.minicontroller.server.screenImageService.MediaProjectionScreenService;
import com.hup.minicontroller.server.service.CursorFloaterService;
import com.hup.minicontroller.server.service.MainService;

/**
 * 本app的安卓服务,功能:
 * .{@link MediaProjectionScreenService}, mediaProjection录屏功能需要app有前台服务,如果本服务被用户关闭,则录屏服务也会收不到图像
 * .{@link CursorFloaterService}, [光标悬浮窗服务]
 * .前台服务也可以实现app被杀后(由系统)自动重启(开发机上可以)
 * <p>
 * 资料:
 * https://www.cnblogs.com/renhui/p/8575299.html
 * 权限:
 * <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
 */
public class AppService extends Service {
    private static final String TAG = AppService.class.getSimpleName();

    /**
     * 切换前台服务状态;
     * 并且会切换录屏服务状态
     */
    public static void switchService(boolean isStart) {
        Log.i(TAG, "switchService: " + isStart);
        if (isStart) {
            Context context = ServerApplication.getContext();
            Intent intent = new Intent(context, AppService.class);
            context.startForegroundService(intent);//minSdkVersion 26
        } else {
            ServerApplication.executeIfExist(AppService.class, Service::stopSelf);
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate: ");
        initForegroundService();
        ServerApplication.putBean(this);
        if (MainService.SWITCH_SCREEN_ON_BOOT) {
            //开启录屏功能,因为此时还在Application.onCreate中,所以需要delay等待Activity启动
            ServerApplication.getBean(MainThreadHandler.class).postDelayed(() ->
                    ServerApplication.getBean(IScreenImageService.class).switchService(true), 300);
        }
    }

    /**
     * 因为是startForegroundService启动的前台服务,所以要初始化,
     * 否则会有异常:RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
     *
     * @apiNote 关于本方法的调用时机 <br>
     * 在 {@link #onCreate()},{@link #onStartCommand(Intent, int, int)}调用都发现问题
     */
    private void initForegroundService() {
        Log.i(TAG, "initForegroundService: ");
        String notificationChannelId = "AppServiceId";
        CharSequence channelName = getClass().getSimpleName();

        //要先创建channel
        NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel channel = new NotificationChannel(notificationChannelId, channelName, NotificationManager.IMPORTANCE_HIGH);
        notificationManager.createNotificationChannel(channel);

        Notification notification = new Builder(getApplicationContext(), notificationChannelId)
                .setContentTitle("录屏服务")//下拉列表里的标题
                .setContentText("ContentText")//上下文内容
                .setWhen(System.currentTimeMillis())//通知发生的时间
                .build();
        /*
        网上说:id!=1时通知栏会有通知,id=0时会屏蔽通知;但开发机上没通知(权限都允许了)???
        开发机的情况:如果是0,则:系统会先调用onDestroy,然后有异常did not then call Service.startForeground(),app强退
         */
        startForeground(1, notification);
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind: ");
        return null;
    }

    /**
     * 触发着:
     * .用户在系统界面可以看见本服务,名字是类名,点击停止服务后会触发本方法
     * .本程序调用 {@link #switchService(boolean)}
     */
    @Override
    public void onDestroy() {
        Log.i(TAG, "onDestroy: ");
        if (MainService.SWITCH_SCREEN_ON_BOOT) {
            //如果是用户停止了服务,则录屏服务(不调用停止代码)也不会收到图像了,所以这里需要更新状态!
            ServerApplication.getBean(IScreenImageService.class).switchService(false);
        }
        stopForeground(true);
        ServerApplication.removeBean(this.getClass());
        super.onDestroy();
    }
}
